

from typing import AsyncGenerator
from application.settings import SQLALCHEMY_DATABASE_URL
from sqlalchemy.orm import DeclarativeBase, declared_attr
from sqlalchemy.ext.asyncio import (create_async_engine, async_sessionmaker,
                                    AsyncSession, AsyncAttrs)

# 创建数据库连接
async_engine = create_async_engine(
    SQLALCHEMY_DATABASE_URL,
    echo=False, echo_pool=False, pool_pre_ping=True,
    pool_recycle=3600, pool_size=5, max_overflow=5,
    connect_args={}
)

# 创建异步会话工厂
session_factory = async_sessionmaker(
    autocommit=False,
    autoflush=False,
    bind=async_engine,       # 异步引擎实例
    expire_on_commit=True,   # 控制提交后是否使实例过期
    class_=AsyncSession      # 自定义会话类（默认为 AsyncSession）
)


class Base(AsyncAttrs, DeclarativeBase):

    @declared_attr.directive
    def __tablename__(cls) -> str:
        table_name = cls.__tablename__
        if not table_name:
            model_name = cls.__name__
            ls = []
            for idx, c in enumerate(model_name):
                if c.isupper() and idx != 0:
                    ls.append('_')
                ls.append(c)

            table_name = "".join(ls).lower()

        return table_name


async def db_getter() -> AsyncGenerator[AsyncSession, None]:
    async with session_factory() as session:
        async with session.begin():
            yield session
